/**
 * 异步并发限制 *
 * @param {Array} requestList 请求列表
 * @param {Number} limit 并发数量
 */
function limitRequest(requestList = [], limit = 2) {
  console.log("任务开始===");
  let count = 0; //正在执行队列数量
  let reqIndex = 0; //执行到的任务序号
  //添加任务
  requestList.forEach(el => {
    dealRequest(el);
  });

  //执行任务
  function dealRequest(el) {
    //如果执行到的任务序号小于请求数量,并且当前正在运行个数<并发量
    if (requestList.length > reqIndex && count < limit) {
      let task = requestList[reqIndex];
      count++;
      reqIndex++;
      task(reqIndex)
        .then(msg => {
          console.log("msg", msg);
          count--;
          dealRequest(task);
          if (count === 0) {
            console.log("任务结束");
          }
        })
        .catch(msg => {
          count--;
          dealRequest(task);
          if (count === 0) {
            console.log("任务结束");
          }
        });
    }
  }
}

//模拟接口请求
function getData(src) {
  return new Promise((resolve, reject) => {
    // 模拟请求时间，小于5s成功，大于5s失败
    let time = parseInt(Math.random() * 10);
    setTimeout(() => {
      if (time < 5) {
        console.log(`第${src}次成功，耗时${time}秒`);
        resolve(src);
      } else {
        console.log(`第${src}次失败，耗时${time}秒`);
        reject(src);
      }
    }, time * 1000);
  });
}

let resList = [];
for (let i = 0; i < 10; i++) {
  resList.push(getData);
}

//测试使用
limitRequest(resList, 3); //一次性最多执行3个任务